package com.lanyou.cook.web.userManagement;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.JsonObject;
import com.lanyou.cook.common.Constants;
import com.lanyou.cook.datadictionary.UserLogOpt;
import com.lanyou.cook.entity.domain.userManagement.Permission;
import com.lanyou.cook.entity.domain.userManagement.Role;
import com.lanyou.cook.entity.domain.userManagement.User;
import com.lanyou.cook.repository.userManagement.PermissionRepository;
import com.lanyou.cook.repository.userManagement.RoleRepository;
import com.lanyou.cook.repository.userManagement.UserRepository;
import com.lanyou.cook.service.UserLogService;
import com.lanyou.cook.web.param.RoleParam;

/**
 * 角色管理相关业务的控制层
 * @author 杨晨睿
 *
 */
@RestController
@RequestMapping(Constants.BASE_URL_API + "/roles")
public class RoleController {

	@Autowired
	private RoleRepository roleRepository;

	@Autowired
	private PermissionRepository permissionRepository;

	@Autowired
	private UserRepository userRepository;

	@Autowired
	private UserLogService userLogService;

	/**
	 * 判断新增的角色是否已经存在
	 * @param roleName 类型:String 待新增的角色名称
	 * @return 类型:boolean 判断后返回的结果(存在返回true,不存在返回false)
	 */
	private boolean checkRoleExists(String roleName) {
		Role role = roleRepository.findByRoleName(roleName);
		if (role != null) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 新增一个角色
	 * @param roleParam 类型:RoleParam 待新增的参数实体
	 * @return 类型:String 判断后返回的结果(存在返回true,不存在返回错误描述)
	 */
	@RequestMapping(value = "/addRole", produces = "application/json", method = RequestMethod.POST)
	@RequiresPermissions(value = { "roleDelegation" })
	@Transactional
	public String addRole(@RequestBody RoleParam roleParam) {
		JsonObject result = new JsonObject();
		if(!checkRoleExists(roleParam.getRoleName())){
			result.addProperty("backValue", "角色名已存在！");
			return result.toString();
		}
		Role role = new Role();

		if (roleParam.getRoleName() != null) {
			role.setRoleName(roleParam.getRoleName());
		}
		if (roleParam.getRemark() != null) {
			role.setRemark(roleParam.getRemark());
		}

		Collection<String> permissionIds = roleParam.getPermissionIds();
		List<Permission> permissions = permissionRepository.findAll(permissionIds);
		role.getPermissions().clear();
		role.getPermissions().addAll(permissions);
		roleRepository.save(Arrays.asList(role));
		userLogService.save(UserLogOpt.MaintenanceRole, null, String.format("新增了角色“%s”", role.getRoleName()));
		result.addProperty("backValue", true);
		return result.toString();
	}
	
	/**
	 * 判断修改的角色是否是默认角色
	 * @param roleId 类型:String 待修改的角色ID
	 * @param roleName 类型:String 待修改的角色名称
	 * @return 类型:boolean 判断后返回的结果(是默认角色且角色名改变了返回true,否则返回false)
	 */
	private boolean checkRoleIsDefault(String roleId,String roleName) {
		if(StringUtils.equals(roleId, Constants.FIXED_ROLE_ID_FOR_ADMIN)
				||StringUtils.equals(roleId, Constants.FIXED_ROLE_ID_FOR_INTERFACE_DEVELOPER)
				||StringUtils.equals(roleId, Constants.FIXED_ROLE_ID_FOR_INTERFACE_MAINTENANCE)
				||StringUtils.equals(roleId, Constants.FIXED_ROLE_ID_FOR_VISITOR)){
			Role role = roleRepository.findOne(Role.idSpecification(roleId));
			if(!StringUtils.equals(role.getRoleName(), roleName)){
				return false;
			}else{
				return true;
			}
		} else {
			return true;
		}
	}
	
	

	/**
	 * 修改一个角色
	 * @param roleParam 类型:RoleParam 待修改的参数实体
	 * @return 类型:String 判断后返回的结果(存在返回true,不存在返回错误描述)
	 */
	@RequestMapping(value = "/updateRole", produces = "application/json", method = RequestMethod.POST)
	@RequiresPermissions(value = { "roleDelegation" })
	@Transactional
	public String updateRole(@RequestBody RoleParam roleParam) {
		JsonObject result = new JsonObject();
		if(!checkRoleIsDefault(roleParam.getId(),roleParam.getRoleName())){
			result.addProperty("backValue", "系统默认角色，不允许重命名！");
			return result.toString();
		}
		Role role = roleRepository.findOne(Role.idSpecification(roleParam.getId()));
		
		if (roleParam.getRoleName() != null) {
			
			if(!StringUtils.equals(roleParam.getRoleName(), role.getRoleName())&&!checkRoleExists(roleParam.getRoleName())){
				result.addProperty("backValue", "角色名已存在！");
				return result.toString();
			}
			
			role.setRoleName(roleParam.getRoleName());
		}
		if (roleParam.getRemark() != null) {
			role.setRemark(roleParam.getRemark());
		}

		Collection<String> permissionIds = roleParam.getPermissionIds();
		List<Permission> permissions = permissionRepository.findAll(permissionIds);
		role.getPermissions().clear();
		role.getPermissions().addAll(permissions);
		roleRepository.save(Arrays.asList(role));
		userLogService.save(UserLogOpt.MaintenanceRole, null, String.format("修改了角色“%s”", role.getRoleName()));
		result.addProperty("backValue", true);
		return result.toString();
	}

	/**
	 * 判断此角色是否分配给了用户
	 * @param roleParam 类型:RoleParam 待判断的参数实体
	 * @return 类型:boolean 判断后返回的结果(存在返回true,不存在返回false)
	 */
	private boolean checkUserExists(@RequestBody RoleParam roleParam) {
		List<User> users = userRepository.findByRole_Id(roleParam.getId());
		if (!users.isEmpty()) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 判断是否是不可删除的角色
	 * @param roleParam 类型: RoleParam 待判断的参数实体
	 * @return 类型:boolean 判断后返回的结果(存在返回true,不存在返回false)
	 */
	private boolean checkIsUnDeleteRole(@RequestBody RoleParam roleParam) {
		if(StringUtils.equals(roleParam.getId(), Constants.FIXED_ROLE_ID_FOR_ADMIN)
				||StringUtils.equals(roleParam.getId(), Constants.FIXED_ROLE_ID_FOR_INTERFACE_DEVELOPER)
				||StringUtils.equals(roleParam.getId(), Constants.FIXED_ROLE_ID_FOR_INTERFACE_MAINTENANCE)
				||StringUtils.equals(roleParam.getId(), Constants.FIXED_ROLE_ID_FOR_VISITOR)){
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 删除一个角色
	 * @param roleParam 类型: RoleParam 待删除的参数实体
	 * @return 类型:String 删除角色返回的结果(删除成功返回true,删除失败返回相对应的错误描述)
	 */
	@RequestMapping(value = "/deleteRole", produces = "application/json", method = RequestMethod.DELETE)
	@RequiresPermissions(value = { "roleDelegation" })
	@Transactional
	public String deleteRole(@RequestBody RoleParam roleParam) {
		JsonObject result = new JsonObject();
		if(!checkUserExists(roleParam)){
			result.addProperty("backValue", "不能删除拥有下属用户的角色!");
			return result.toString();
		}
		
		if(!checkIsUnDeleteRole(roleParam)){
			result.addProperty("backValue", "不允许删除系统默认的角色");
			return result.toString();
		}
		
		
		Role role = roleRepository.findOne(Role.idSpecification(roleParam.getId()));
		roleRepository.delete(Arrays.asList(role));
		userLogService.save(UserLogOpt.MaintenanceRole, null, String.format("删除 了角色“%s”", role.getRoleName()));
		result.addProperty("backValue", true);
		return result.toString();
	}

}
